<script setup>
import {HomeFilled} from "@element-plus/icons-vue";
import { ref, reactive, onMounted, watch } from 'vue'
import { Edit } from '@element-plus/icons-vue'
import axios from 'axios'
import { useRouter, useRoute } from "vue-router";
import { ElMessage, ElLoading } from 'element-plus'
import request from "@/utils/request";

const router = useRouter()
const route = useRoute()

// 课程列表和选择
const courseList = ref([])
const selectedCourseId = ref('')

// 课程和章节信息
const currentCourse = ref({
    id: null,
    name: '未命名课程'
})
const chapters = ref([])
const loadingContent = ref(false)
const learningProgress = ref({}) // 用于存储学习进度

// 当前选中内容
const activeChapter = ref('')
const currentContent = ref(null)

// 笔记相关状态
const drawerVisible = ref(false)
const confirmDialogVisible = ref(false)
const noteForm = reactive({
    title: '',
    content: ''
})
const existingNote = ref(null)

const getStuId = () => {
  try {
    const rawInfo = localStorage.getItem('studentUserInfo')
    if (!rawInfo) throw new Error('无登录信息')

    const userInfo = JSON.parse(rawInfo)
    if (!userInfo?.stu_id) {
      localStorage.removeItem('studentUserInfo')
      router.push('/student/login')
      return null
    }
    return userInfo.stu_id
  } catch (e) {
    console.error('学生ID获取失败:', e)
    return null
  }
}

defineExpose({
  getStuId
})

// 加载课程列表
const fetchCourseList = async () => {
    try {
        const stuId = getStuId()
        if (!stuId) {
            ElMessage.error('获取学生信息失败，请重新登录')
            return
        }

        const { data } = await request.get('/api/student/course-selection/', {
            params: {
                stu_id: stuId,
                username: stuId
            }
        })

        if (Array.isArray(data) && data.length > 0) {
            // 获取已选课程ID列表
            const courseIds = data

            // 获取所有课程详情
            const coursesResponse = await request.get('/api/student/course/')
            let allCourses = []

            if (Array.isArray(coursesResponse.data)) {
                allCourses = coursesResponse.data
            } else if (coursesResponse.data && Array.isArray(coursesResponse.data.data)) {
                allCourses = coursesResponse.data.data
            }

            // 筛选出已选课程
            if (allCourses.length > 0) {
                courseList.value = allCourses
                    .filter(course => courseIds.includes(Number(course.id)))
                    .map(course => ({
                        value: course.id,
                        label: course.name || `课程${course.id}`
                    }))
            }
        }

        if (courseList.value.length === 0) {
            // 使用默认测试数据
            courseList.value = [
                { value: '1', label: '数据结构' },
                { value: '3', label: '计算机网络' },
                { value: '5', label: '软件工程' }
            ]
        }
    } catch (error) {
        console.error('获取课程列表失败:', error)
        ElMessage.warning('获取课程列表失败，使用默认数据')

        // 使用默认测试数据
        courseList.value = [
            { value: '1', label: '数据结构' },
            { value: '3', label: '计算机网络' },
            { value: '5', label: '软件工程' }
        ]
    }
}

// 处理课程变更
const handleCourseChange = (courseId) => {
    if (!courseId) return

    // 更新URL但不刷新页面
    router.push({
        name: 'CourseStudy',
        params: { courseId },
        replace: true
    })

    // 加载新的课程内容
    currentCourse.value.id = courseId
    fetchCourseStructure()

    // 重置当前选中的章节
    activeChapter.value = ''
    currentContent.value = null
}

// 处理章节选择
const handleChapterSelect = (index) => {
    activeChapter.value = index
    fetchContent(index)
    // 在localStorage中保存当前选中的知识点ID
    localStorage.setItem('lastSelectedPoint', index)
}

// 获取知识点内容
const fetchContent = async (pointId) => {
    loadingContent.value = true
    try {
        const { data } = await axios.get(`/api/student/course/point/${pointId}/`)
        currentContent.value = data

        // 记录学习进度
        recordProgress(pointId)

        // 检查是否有已存在的笔记
        fetchExistingNote(pointId)
    } catch (error) {
        console.error('获取内容失败:', error)
        ElMessage.warning('无法从服务器获取知识点内容，使用本地数据')

        // 使用本地模拟数据
        try {
            const mockData = await getMockKnowledgePoint(parseInt(pointId))
            currentContent.value = mockData
        } catch (mockError) {
            ElMessage.error('本地数据获取失败')
            // 最后的备选数据
            currentContent.value = {
                id: pointId,
                title: '测试知识点',
                detail: '<p>这是一个测试知识点内容，由于API请求失败而显示。</p>',
                chapter_title: '测试章节'
            }
        }
    } finally {
        loadingContent.value = false
    }
}

// 获取课程结构
const fetchCourseStructure = async () => {
    const loading = ElLoading.service({
        lock: true,
        text: '加载课程结构...',
        background: 'rgba(255, 255, 255, 0.7)'
    })

    try {
        const { data } = await axios.get(`/api/student/course/structure/${currentCourse.value.id}`)
        chapters.value = data.chapters
        currentCourse.value.name = data.course.course_name

        // 加载已完成的知识点进度
        data.chapters.forEach(chapter => {
            chapter.points.forEach(point => {
                if (point.is_completed) {
                    learningProgress.value[point.id] = true
                }
            })
        })

        // 如果没有查询参数指定知识点，尝试从localStorage恢复上次访问的知识点
        if (!route.query.point) {
            const lastPoint = localStorage.getItem('lastSelectedPoint')
            if (lastPoint) {
                handleChapterSelect(lastPoint)
            }
        }
    } catch (error) {
        console.error('获取课程结构失败:', error)
        ElMessage.warning('无法从服务器获取课程结构，使用本地数据')

        // 使用本地模拟数据
        try {
            const mockData = await getMockCourseStructure()
            chapters.value = mockData.chapters
            currentCourse.value.name = mockData.course.course_name

            // 加载已完成的知识点进度
            mockData.chapters.forEach(chapter => {
                chapter.points.forEach(point => {
                    if (point.is_completed) {
                        learningProgress.value[point.id] = true
                    }
                })
            })
        } catch (mockError) {
            ElMessage.error('本地数据获取失败')
            // 模拟数据
            chapters.value = [
                {
                    chapter_id: 1,
                    charter_title: '测试章节1',
                    points: [
                        { id: 1, title: '测试知识点1.1' },
                        { id: 2, title: '测试知识点1.2' }
                    ]
                },
                {
                    chapter_id: 2,
                    charter_title: '测试章节2',
                    points: [
                        { id: 3, title: '测试知识点2.1' },
                        { id: 4, title: '测试知识点2.2' }
                    ]
                }
            ]
        }
    } finally {
        loading.close()
    }
}

// 获取已有笔记
const fetchExistingNote = async (pointId) => {
    try {
        const stuId = getStuId();
        const { data } = await axios.get(`/api/student/notes/${pointId}/`, {
            params: {
                stu_id: stuId,
                username: stuId
            }
        })
        if (data.notes && data.notes.length > 0) {
            existingNote.value = data.notes[0]
            noteForm.title = existingNote.value.note_title
            noteForm.content = existingNote.value.note_content
        } else {
            existingNote.value = null
            noteForm.title = `${currentContent.value.title}的笔记`
            noteForm.content = ''
        }
    } catch (error) {
        console.error('获取笔记失败:', error)
        ElMessage.warning('无法从服务器获取笔记，使用本地数据')

        // 使用本地模拟数据
        try {
            const { notes } = await getMockNotes(parseInt(pointId))
            if (notes && notes.length > 0) {
                existingNote.value = notes[0]
                noteForm.title = existingNote.value.note_title
                noteForm.content = existingNote.value.note_content
            } else {
                existingNote.value = null
                noteForm.title = `${currentContent.value.title}的笔记`
                noteForm.content = ''
            }
        } catch (mockError) {
            noteForm.title = `${currentContent.value.title}的笔记`
            noteForm.content = ''
        }
    }
}

// 记录学习进度
const recordProgress = async (pointId) => {
    try {
        const stuId = getStuId();
        await axios.post('/api/student/course/learning/', {
            point_id: pointId,
            is_completed: true,
            stu_id: stuId,
            username: stuId
        })
        // 更新本地进度状态
        learningProgress.value[pointId] = true

        // 更新UI中的进度显示
        chapters.value.forEach(chapter => {
            chapter.points.forEach(point => {
                if (point.id == pointId) {
                    point.is_completed = true
                }
            })
        })
    } catch (error) {
        console.error('进度记录失败:', error)
        ElMessage.warning('无法保存学习进度到服务器，仅在本地记录')

        // 使用本地模拟数据，依然更新UI显示
        try {
            await mockRecordProgress()
            learningProgress.value[pointId] = true
            chapters.value.forEach(chapter => {
                chapter.points.forEach(point => {
                    if (point.id == pointId) {
                        point.is_completed = true
                    }
                })
            })

            // 保存到 localStorage 作为临时解决方案
            const savedProgress = JSON.parse(localStorage.getItem('learningProgress') || '{}')
            savedProgress[pointId] = true
            localStorage.setItem('learningProgress', JSON.stringify(savedProgress))
        } catch (mockError) {
            console.error('本地进度记录失败:', mockError)
        }
    }
}

// 打开笔记抽屉
const openNoteDrawer = () => {
    if (!currentContent.value) {
        ElMessage.warning('请先选择一个知识点')
        return
    }
    drawerVisible.value = true
}

// 保存笔记
const handleSaveNote = () => {
    if (!noteForm.title.trim()) {
        ElMessage.warning('笔记标题不能为空')
        return
    }
    confirmDialogVisible.value = true
}

// 确认保存笔记
const confirmSaveNote = async () => {
    try {
        const stuId = getStuId();
        await axios.post('/api/student/notes/', {
            point_id: currentContent.value.id,
            note_title: noteForm.title,
            note_content: noteForm.content,
            stu_id: stuId,
            username: stuId,
            course_id: currentCourse.value.id
        })
        ElMessage.success('笔记保存成功')
        confirmDialogVisible.value = false
        drawerVisible.value = false
    } catch (error) {
        console.error('保存笔记失败:', error)
        ElMessage.warning('无法保存笔记到服务器，尝试本地保存')

        // 使用本地模拟保存
        try {
            await mockSaveNote()
            ElMessage.success('笔记已在本地保存')
            confirmDialogVisible.value = false
            drawerVisible.value = false

            // 保存到 localStorage 作为临时解决方案
            const savedNotes = JSON.parse(localStorage.getItem('studyNotes') || '{}')
            savedNotes[currentContent.value.id] = {
                title: noteForm.title,
                content: noteForm.content,
                timestamp: new Date().toISOString()
            }
            localStorage.setItem('studyNotes', JSON.stringify(savedNotes))
        } catch (mockError) {
            ElMessage.error('本地保存失败')
        }
    }
}

// 返回首页
const backToHome = () => {
    router.push('/student/Homepage/PersonalHomepage')
}

// 初始化时加载本地进度
const loadLocalProgress = () => {
    try {
        const savedProgress = JSON.parse(localStorage.getItem('learningProgress') || '{}')
        for (const pointId in savedProgress) {
            if (savedProgress[pointId]) {
                learningProgress.value[pointId] = true
            }
        }
    } catch (error) {
        console.error('加载本地进度失败:', error)
    }
}

// 初始化加载
onMounted(async () => {
    // 获取路由参数中的courseId
    const courseId = route.params.courseId;

    if (!courseId) {
        ElMessage.warning('未提供课程ID，请从课程列表选择一个课程');
        currentCourse.value.name = '未选择课程';
        return;
    }

    // 加载课程列表和选中课程
    await fetchCourseList();
    selectedCourseId.value = courseId;

    currentCourse.value.id = courseId;
    loadLocalProgress(); // 先加载本地进度
    await fetchCourseStructure();
    if (route.query.point) {
        handleChapterSelect(route.query.point);
    }
});

// 模拟函数（当API请求失败时使用）
const getMockCourseStructure = async () => {
    // 模拟网络延迟
    await new Promise(resolve => setTimeout(resolve, 300));

    // 根据课程ID生成不同的模拟课程结构
    const courseId = Number(currentCourse.value.id);
    let courseName = '';
    let chapters = [];

    // 为不同课程ID生成对应的课程结构
    switch (courseId) {
        case 1: // 数据结构课程
            courseName = '数据结构与算法';
            chapters = [
                {
                    chapter_id: 1,
                    charter_title: '第一章：数据结构基础',
                    points: [
                        { id: 101, title: '1.1 数据结构概述', is_completed: true },
                        { id: 102, title: '1.2 算法复杂度分析', is_completed: true },
                        { id: 103, title: '1.3 线性结构与非线性结构', is_completed: false }
                    ]
                },
                {
                    chapter_id: 2,
                    charter_title: '第二章：线性表',
                    points: [
                        { id: 201, title: '2.1 顺序表的实现与操作', is_completed: false },
                        { id: 202, title: '2.2 单链表结构', is_completed: false },
                        { id: 203, title: '2.3 双向链表与循环链表', is_completed: false },
                        { id: 204, title: '2.4 线性表的应用', is_completed: false }
                    ]
                },
                {
                    chapter_id: 3,
                    charter_title: '第三章：栈与队列',
                    points: [
                        { id: 301, title: '3.1 栈的定义与实现', is_completed: false },
                        { id: 302, title: '3.2 栈的应用：表达式求值', is_completed: false },
                        { id: 303, title: '3.3 队列的定义与实现', is_completed: false },
                        { id: 304, title: '3.4 队列的应用：广度优先搜索', is_completed: false }
                    ]
                },
                {
                    chapter_id: 4,
                    charter_title: '第四章：树与二叉树',
                    points: [
                        { id: 401, title: '4.1 树的基本概念', is_completed: false },
                        { id: 402, title: '4.2 二叉树的性质', is_completed: false },
                        { id: 403, title: '4.3 二叉树的遍历', is_completed: false },
                        { id: 404, title: '4.4 二叉搜索树', is_completed: false },
                        { id: 405, title: '4.5 平衡二叉树', is_completed: false }
                    ]
                }
            ];
            break;

        case 3: // 计算机网络课程
            courseName = '计算机网络';
            chapters = [
                {
                    chapter_id: 1,
                    charter_title: '第一章：计算机网络概述',
                    points: [
                        { id: 101, title: '1.1 网络体系结构', is_completed: false },
                        { id: 102, title: '1.2 OSI参考模型', is_completed: false },
                        { id: 103, title: '1.3 TCP/IP协议族', is_completed: false }
                    ]
                },
                {
                    chapter_id: 2,
                    charter_title: '第二章：物理层',
                    points: [
                        { id: 201, title: '2.1 数据通信基础', is_completed: false },
                        { id: 202, title: '2.2 传输介质', is_completed: false },
                        { id: 203, title: '2.3 信道复用技术', is_completed: false },
                        { id: 204, title: '2.4 数字调制与编码', is_completed: false }
                    ]
                },
                {
                    chapter_id: 3,
                    charter_title: '第三章：数据链路层',
                    points: [
                        { id: 301, title: '3.1 数据链路层功能', is_completed: false },
                        { id: 302, title: '3.2 差错检测与纠正', is_completed: false },
                        { id: 303, title: '3.3 介质访问控制协议', is_completed: false },
                        { id: 304, title: '3.4 以太网', is_completed: false }
                    ]
                },
                {
                    chapter_id: 4,
                    charter_title: '第四章：网络层',
                    points: [
                        { id: 401, title: '4.1 IP协议', is_completed: false },
                        { id: 402, title: '4.2 IP地址与子网划分', is_completed: false },
                        { id: 403, title: '4.3 路由协议', is_completed: false },
                        { id: 404, title: '4.4 IPv6', is_completed: false }
                    ]
                },
                {
                    chapter_id: 5,
                    charter_title: '第五章：传输层',
                    points: [
                        { id: 501, title: '5.1 UDP协议', is_completed: false },
                        { id: 502, title: '5.2 TCP协议', is_completed: false },
                        { id: 503, title: '5.3 TCP流量控制', is_completed: false },
                        { id: 504, title: '5.4 TCP拥塞控制', is_completed: false }
                    ]
                }
            ];
            break;

        case 5: // 软件工程课程
            courseName = '软件工程';
            chapters = [
                {
                    chapter_id: 1,
                    charter_title: '第一章：软件工程导论',
                    points: [
                        { id: 101, title: '1.1 软件工程概述', is_completed: false },
                        { id: 102, title: '1.2 软件生命周期', is_completed: false },
                        { id: 103, title: '1.3 软件过程模型', is_completed: false }
                    ]
                },
                {
                    chapter_id: 2,
                    charter_title: '第二章：需求分析',
                    points: [
                        { id: 201, title: '2.1 需求获取技术', is_completed: false },
                        { id: 202, title: '2.2 用例分析', is_completed: false },
                        { id: 203, title: '2.3 需求规约', is_completed: false },
                        { id: 204, title: '2.4 需求验证', is_completed: false }
                    ]
                },
                {
                    chapter_id: 3,
                    charter_title: '第三章：软件设计',
                    points: [
                        { id: 301, title: '3.1 架构设计', is_completed: false },
                        { id: 302, title: '3.2 面向对象设计', is_completed: false },
                        { id: 303, title: '3.3 设计模式', is_completed: false },
                        { id: 304, title: '3.4 模块设计', is_completed: false }
                    ]
                },
                {
                    chapter_id: 4,
                    charter_title: '第四章：软件测试',
                    points: [
                        { id: 401, title: '4.1 测试策略', is_completed: false },
                        { id: 402, title: '4.2 单元测试', is_completed: false },
                        { id: 403, title: '4.3 集成测试', is_completed: false },
                        { id: 404, title: '4.4 系统测试', is_completed: false },
                        { id: 405, title: '4.5 自动化测试', is_completed: false }
                    ]
                },
                {
                    chapter_id: 5,
                    charter_title: '第五章：软件项目管理',
                    points: [
                        { id: 501, title: '5.1 项目规划', is_completed: false },
                        { id: 502, title: '5.2 风险管理', is_completed: false },
                        { id: 503, title: '5.3 质量管理', is_completed: false },
                        { id: 504, title: '5.4 配置管理', is_completed: false }
                    ]
                }
            ];
            break;

        default: // 默认课程结构
            courseName = `课程${courseId}`;
            chapters = [
                {
                    chapter_id: 1,
                    charter_title: '第一章：基础概念',
                    points: [
                        { id: 101, title: '1.1 课程概述', is_completed: false },
                        { id: 102, title: '1.2 基本原理', is_completed: false },
                        { id: 103, title: '1.3 核心术语', is_completed: false }
                    ]
                },
                {
                    chapter_id: 2,
                    charter_title: '第二章：进阶内容',
                    points: [
                        { id: 201, title: '2.1 理论应用', is_completed: false },
                        { id: 202, title: '2.2 实践方法', is_completed: false },
                        { id: 203, title: '2.3 高级技巧', is_completed: false }
                    ]
                },
                {
                    chapter_id: 3,
                    charter_title: '第三章：实际案例',
                    points: [
                        { id: 301, title: '3.1 案例分析', is_completed: false },
                        { id: 302, title: '3.2 问题解决', is_completed: false },
                        { id: 303, title: '3.3 最佳实践', is_completed: false }
                    ]
                }
            ];
    }

    return {
        course: {
            course_id: courseId,
            course_name: courseName,
            course_intro: `${courseName}是计算机科学领域的重要课程，涵盖了从基础理论到实际应用的多方面知识。`
        },
        chapters: chapters
    };
}

const getMockKnowledgePoint = async (pointId) => {
    // 模拟网络延迟
    await new Promise(resolve => setTimeout(resolve, 300));

    // 课程知识点内容
    const mockPoints = {
        // 数据结构课程知识点
        101: {
            id: 101,
            title: '1.1 数据结构概述',
            detail: `<h3>数据结构概述</h3>
            <p>数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。</p>
            <p>通常情况下，精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关。</p>

            <h4>数据结构的分类</h4>
            <ul>
              <li><strong>线性结构</strong>：数据元素之间存在一对一的线性关系，如：数组、链表、栈、队列等</li>
              <li><strong>非线性结构</strong>：数据元素之间存在一对多或多对多的关系，如：树、图等</li>
            </ul>

            <h4>数据结构的基本操作</h4>
            <ul>
              <li>插入</li>
              <li>删除</li>
              <li>修改</li>
              <li>查找</li>
              <li>排序</li>
            </ul>

            <p>选择合适的数据结构对实现高效算法至关重要，也是计算机科学中的核心课题。</p>`,
            chapter_title: '第一章：数据结构基础'
        },
        102: {
            id: 102,
            title: '1.2 算法复杂度分析',
            detail: `<h3>算法复杂度分析</h3>
            <p>算法复杂度是评价算法优劣的一个重要标准，通常从时间复杂度和空间复杂度两个维度进行考量。</p>

            <h4>时间复杂度</h4>
            <p>时间复杂度用来估计算法运行时间随输入规模增长的变化趋势，通常用大O符号表示。</p>
            <p>常见的时间复杂度有：</p>
            <ul>
              <li><strong>O(1)</strong> - 常数时间，与输入规模无关</li>
              <li><strong>O(log n)</strong> - 对数时间，如二分查找</li>
              <li><strong>O(n)</strong> - 线性时间，如简单遍历</li>
              <li><strong>O(n log n)</strong> - 线性对数时间，如快速排序</li>
              <li><strong>O(n²)</strong> - 平方时间，如简单的排序算法（冒泡、选择）</li>
              <li><strong>O(2^n)</strong> - 指数时间，如递归斐波那契</li>
            </ul>

            <h4>空间复杂度</h4>
            <p>空间复杂度用来评估算法在运行过程中临时占用存储空间大小的量度。</p>

            <h4>复杂度分析案例</h4>
            <pre>
// 时间复杂度：O(n)
function linearSearch(arr, target) {
    for (let i = 0; i < arr.length; i++) {
        if (arr[i] === target) return i;
    }
    return -1;
}

// 时间复杂度：O(log n)
function binarySearch(sortedArr, target) {
    let left = 0;
    let right = sortedArr.length - 1;

    while (left <= right) {
        let mid = Math.floor((left + right) / 2);

        if (sortedArr[mid] === target) return mid;
        if (sortedArr[mid] < target) left = mid + 1;
        else right = mid - 1;
    }

    return -1;
}
</pre>`,
            chapter_title: '第一章：数据结构基础'
        },
        103: {
            id: 103,
            title: '1.3 线性结构与非线性结构',
            detail: `<h3>线性结构与非线性结构</h3>
            <p>数据结构可以分为线性结构和非线性结构两大类。</p>

            <h4>线性结构</h4>
            <p>线性结构是一个有序数据元素的集合，其中除第一个元素外，每个元素有且仅有一个前驱；除最后一个元素外，每个元素有且仅有一个后继。</p>
            <p>主要的线性结构包括：</p>
            <ul>
              <li><strong>数组</strong>：连续内存空间，支持随机访问</li>
              <li><strong>链表</strong>：非连续内存，通过指针链接</li>
              <li><strong>栈</strong>：后进先出(LIFO)的线性表</li>
              <li><strong>队列</strong>：先进先出(FIFO)的线性表</li>
            </ul>

            <h4>非线性结构</h4>
            <p>非线性结构中，数据元素之间的关系是一对多或多对多的。</p>
            <p>主要的非线性结构包括：</p>
            <ul>
              <li><strong>树</strong>：层次关系的数据结构，每个结点有零个或多个子节点</li>
              <li><strong>图</strong>：由结点和边组成的数据结构，表示多对多关系</li>
              <li><strong>散列表</strong>：根据关键码直接访问的数据结构</li>
            </ul>

            <h4>选择合适的数据结构</h4>
            <p>选择何种数据结构需要考虑以下因素：</p>
            <ul>
              <li>问题的特性（如需要频繁插入删除还是查找）</li>
              <li>空间复杂度要求</li>
              <li>时间复杂度要求</li>
              <li>实现的难易程度</li>
            </ul>`,
            chapter_title: '第一章：数据结构基础'
        },

        // 计算机网络课程知识点
        301: {
            id: 301,
            title: '3.1 数据链路层功能',
            detail: `<h3>数据链路层功能</h3>
            <p>数据链路层是OSI参考模型中的第二层，负责在物理层提供的比特流上实现可靠的点对点数据传输。</p>

            <h4>主要功能</h4>
            <ol>
              <li><strong>封装成帧</strong>：将网络层下发的数据包封装成帧，添加帧头和帧尾</li>
              <li><strong>差错检测</strong>：检测传输过程中可能出现的比特错误</li>
              <li><strong>可靠传输</strong>：提供可靠的数据传输服务，处理丢失、重复等问题</li>
              <li><strong>流量控制</strong>：控制发送方的发送速率，使之与接收方的处理能力相匹配</li>
              <li><strong>介质访问控制</strong>：解决多个设备共享传输介质时的访问控制问题</li>
            </ol>

            <h4>数据链路层协议</h4>
            <ul>
              <li><strong>HDLC</strong>（高级数据链路控制）</li>
              <li><strong>PPP</strong>（点对点协议）</li>
              <li><strong>以太网协议</strong></li>
              <li><strong>SDLC</strong>（同步数据链路控制）</li>
            </ul>

            <h4>数据链路层设备</h4>
            <p>数据链路层主要的网络设备是网桥和交换机。这些设备通过MAC地址进行数据转发。</p>

            <h4>MAC地址</h4>
            <p>MAC地址是数据链路层使用的物理地址，通常被固化在网卡ROM中，全球唯一。一个典型的MAC地址由48位二进制组成，通常表示为12个十六进制数字，如：00-0C-29-7A-CE-F5。</p>`,
            chapter_title: '第三章：数据链路层'
        },

        // 软件工程课程知识点
        202: {
            id: 202,
            title: '2.2 用例分析',
            detail: `<h3>用例分析</h3>
            <p>用例分析是需求分析阶段的一种重要技术，通过用例来描述系统的功能需求，展示系统与外部参与者（用户或其他系统）之间的交互。</p>

            <h4>用例的组成元素</h4>
            <ul>
              <li><strong>参与者（Actor）</strong>：与系统进行交互的外部实体，可以是人、组织或外部系统</li>
              <li><strong>用例（Use Case）</strong>：描述系统为参与者提供的功能或服务</li>
              <li><strong>关系</strong>：用例之间或参与者与用例之间的联系，如包含、扩展、泛化等</li>
            </ul>

            <h4>用例图</h4>
            <p>用例图是用例分析的可视化表示，它展示了系统、参与者和用例之间的关系。用例图是UML（统一建模语言）中的一种图表。</p>

            <h4>用例文档</h4>
            <p>用例文档详细描述了用例的执行流程，通常包括：</p>
            <ol>
              <li>用例名称</li>
              <li>参与者</li>
              <li>前置条件</li>
              <li>后置条件</li>
              <li>主要流程（基本路径）</li>
              <li>备选流程（替代路径）</li>
              <li>异常流程</li>
              <li>业务规则</li>
            </ol>

            <h4>用例分析的步骤</h4>
            <ol>
              <li>确定系统边界</li>
              <li>识别参与者</li>
              <li>确定用例</li>
              <li>建立用例图</li>
              <li>编写用例文档</li>
              <li>用例评审</li>
            </ol>

            <h4>用例分析的优势</h4>
            <ul>
              <li>从用户视角描述系统功能</li>
              <li>便于与客户沟通</li>
              <li>作为开发和测试的基础</li>
              <li>有助于确保需求的完整性</li>
            </ul>`,
            chapter_title: '第二章：需求分析'
        },

        // 通用知识点模板
        201: {
            id: 201,
            title: '2.1 顺序表的实现与操作',
            detail: `<h3>顺序表的实现与操作</h3>
            <p>顺序表是线性表的一种实现方式，它使用连续的内存空间存储数据元素。</p>

            <h4>特点</h4>
            <ul>
              <li>随机访问：可以在O(1)时间复杂度内访问任意位置的元素</li>
              <li>存储密度高：不需要存储额外的指针信息</li>
              <li>插入和删除操作效率较低，需要移动元素</li>
              <li>扩容操作成本较高</li>
            </ul>

            <h4>基本操作</h4>
            <ol>
              <li><strong>初始化</strong>：分配内存空间，设置表的长度为0</li>
              <li><strong>插入</strong>：将元素插入到指定位置，后续元素后移</li>
              <li><strong>删除</strong>：删除指定位置的元素，后续元素前移</li>
              <li><strong>查找</strong>：按值查找或按索引查找元素</li>
              <li><strong>更新</strong>：修改指定位置的元素值</li>
            </ol>

            <h4>代码实现示例(C语言)</h4>
            <pre>
#define MAXSIZE 100

typedef struct {
    int data[MAXSIZE];  // 存储元素的数组
    int length;         // 当前长度
} SqList;

// 初始化
void InitList(SqList *L) {
    L->length = 0;
}

// 插入操作
int ListInsert(SqList *L, int i, int e) {
    // 判断i的范围是否有效
    if (i < 1 || i > L->length + 1) return 0;

    // 表满无法插入
    if (L->length >= MAXSIZE) return 0;

    // 将第i个位置及之后的元素后移
    for (int j = L->length; j >= i; j--) {
        L->data[j] = L->data[j-1];
    }

    // 插入元素
    L->data[i-1] = e;

    // 表长加1
    L->length++;

    return 1;
}

// 删除操作
int ListDelete(SqList *L, int i) {
    // 判断i的范围是否有效
    if (i < 1 || i > L->length) return 0;

    // 将第i个位置之后的元素前移
    for (int j = i; j < L->length; j++) {
        L->data[j-1] = L->data[j];
    }

    // 表长减1
    L->length--;

    return 1;
}
</pre>`,
            chapter_title: '第二章：线性表'
        },

        // 默认知识点模板
        999: {
            id: 999,
            title: '知识点标题',
            detail: `<h3>知识点详情</h3>
            <p>这是一个默认的知识点内容模板，包含了基本的HTML格式和结构。</p>

            <h4>小标题</h4>
            <ul>
              <li>列表项1</li>
              <li>列表项2</li>
              <li>列表项3</li>
            </ul>

            <p>更多详细内容...</p>`,
            chapter_title: '默认章节'
        }
    };

    // 如果在预定义的知识点中找到，则返回该知识点
    if (mockPoints[pointId]) {
        return mockPoints[pointId];
    }

    // 否则根据pointId生成动态知识点内容
    const chapterId = Math.floor(pointId / 100);
    const pointNum = pointId % 100;

    return {
        id: pointId,
        title: `${chapterId}.${pointNum} 动态生成的知识点`,
        detail: `<h3>知识点 ${chapterId}.${pointNum}</h3>
        <p>这是一个动态生成的知识点内容。知识点ID: ${pointId}</p>

        <h4>知识要点</h4>
        <ul>
          <li>这是第${chapterId}章的第${pointNum}个知识点</li>
          <li>通过ID动态生成的内容</li>
          <li>包含基本的格式和结构</li>
        </ul>

        <h4>补充资料</h4>
        <p>更多内容请参考课程教材和相关资源。</p>`,
        chapter_title: `第${chapterId}章`
    };
}

const getMockNotes = async (pointId) => {
    // 模拟网络延迟
    await new Promise(resolve => setTimeout(resolve, 300));

    // 尝试从localStorage获取保存的笔记
    try {
        const savedNotes = JSON.parse(localStorage.getItem('studyNotes') || '{}')
        if (savedNotes[pointId]) {
            return {
                notes: [{
                    id: 1000 + pointId,
                    note_title: savedNotes[pointId].title,
                    note_content: savedNotes[pointId].content,
                    created_at: savedNotes[pointId].timestamp
                }]
            };
        }
    } catch (e) {
        console.error('读取本地笔记失败', e);
    }

    // 预定义的示例笔记
    const exampleNotes = {
        101: {
            id: 2101,
            note_title: "数据结构概述笔记",
            note_content: "数据结构是计算机存储、组织数据的方式。主要分为线性结构和非线性结构两大类。\n\n线性结构包括：数组、链表、栈、队列\n非线性结构包括：树、图、散列表\n\n选择数据结构时需要考虑：时间复杂度、空间复杂度、实际应用场景。",
            created_at: "2023-05-15T10:30:00Z"
        },
        102: {
            id: 2102,
            note_title: "算法复杂度笔记",
            note_content: "时间复杂度：评估算法执行时间随输入规模增长的趋势\n\n常见时间复杂度从小到大排序：\nO(1) < O(log n) < O(n) < O(n log n) < O(n²) < O(2^n) < O(n!)\n\n空间复杂度：评估算法执行过程中占用的存储空间\n\n复杂度分析的重点是渐进行为，而非具体常数。",
            created_at: "2023-05-16T14:45:00Z"
        },
        202: {
            id: 2202,
            note_title: "用例分析要点",
            note_content: "用例分析步骤：\n1. 确定系统边界\n2. 识别参与者\n3. 确定用例\n4. 建立用例图\n5. 编写用例文档\n\n用例文档结构：\n- 用例名称\n- 参与者\n- 前置条件\n- 主要流程\n- 备选流程\n- 后置条件\n\n注意：用例应该从参与者的角度描述，而非系统内部实现。",
            created_at: "2023-06-10T09:20:00Z"
        },
        301: {
            id: 2301,
            note_title: "数据链路层笔记",
            note_content: "数据链路层主要功能：\n- 封装成帧\n- 差错检测和纠正\n- 媒体访问控制\n- 流量控制\n\n重要协议：\n- 以太网\n- PPP\n- HDLC\n\nMAC地址：48位，全球唯一，用于局域网内通信。\n交换机：工作在数据链路层的设备，根据MAC地址转发数据帧。",
            created_at: "2023-04-22T16:15:00Z"
        }
    };

    // 如果有预定义的笔记，返回它
    if (exampleNotes[pointId]) {
        return {
            notes: [exampleNotes[pointId]]
        };
    }

    // 如果没有本地保存的笔记，返回空数组
    return { notes: [] };
}

const mockRecordProgress = async () => {
    // 模拟网络延迟
    await new Promise(resolve => setTimeout(resolve, 300));
    return { status: 'success', message: '进度记录成功' };
}

const mockSaveNote = async () => {
    // 模拟网络延迟
    await new Promise(resolve => setTimeout(resolve, 300));
    return { status: 'success', message: '笔记保存成功', note_id: Date.now() };
}

// 监听路由变化，以便在URL包含知识点ID时加载对应内容
watch(() => route.query.point, (newPointId) => {
    if (newPointId) {
        handleChapterSelect(newPointId)
    }
})

// 监听路由参数变化，以便在URL参数变化时加载对应课程
watch(() => route.params.courseId, (newCourseId) => {
    if (newCourseId && newCourseId !== currentCourse.value.id) {
        selectedCourseId.value = newCourseId;
        currentCourse.value.id = newCourseId;
        fetchCourseStructure();
    }
})

// 切换聊天窗口显示/隐藏
const toggleChat = () => {
    const container = document.getElementById('chatContainer');
    if (container.style.display === 'none' || container.style.display === '') {
        container.style.display = 'block';
    } else {
        container.style.display = 'none';
    }
}

</script>

<template>
    <div class="course-study-wrapper">
        <el-container class="course-study-container">
            <el-header style="padding: 10px 20px;">
                <el-row>
                    <el-col :span="4">
                        <el-icon size="26" color="black">
                            <HomeFilled @click="backToHome"/>
                        </el-icon>
                    </el-col>
                    <el-col :span="16">
                        <div class="course-selector">
                            <el-select
                                v-model="selectedCourseId"
                                placeholder="请选择课程"
                                style="width: 200px"
                                @change="handleCourseChange"
                            >
                                <el-option
                                    v-for="course in courseList"
                                    :key="course.value"
                                    :label="course.label"
                                    :value="course.value"
                                />
                            </el-select>
                            <h3 class="course-title">{{ currentCourse.name }}</h3>
                        </div>
                    </el-col>
                    <el-col :span="4" />
                </el-row>
            </el-header>
            <el-main class="compact-main">
                <div class="main-content">
                    <el-aside width="250px" class="point_list">
                        <el-menu
                            :default-active="activeChapter"
                            @select="handleChapterSelect"
                        >
                            <el-sub-menu
                                v-for="chapter in chapters"
                                :key="chapter.chapter_id"
                                :index="chapter.chapter_id.toString()"
                            >
                                <template #title>{{ chapter.charter_title }}</template>
                                <el-menu-item
                                    v-for="point in chapter.points"
                                    :key="point.id"
                                    :index="point.id.toString()"
                                >
                                    <div class="knowledge-point">
                                        <span>{{ point.title }}</span>
                                        <el-tag v-if="point.is_completed || learningProgress[point.id]"
                                               size="small"
                                               type="success">
                                            已学习
                                        </el-tag>
                                    </div>
                                </el-menu-item>
                            </el-sub-menu>
                        </el-menu>
                    </el-aside>
                    <el-main class="point_content">
                        <div v-if="loadingContent">
                            <el-skeleton :rows="10" animated />
                        </div>
                        <div v-else-if="currentContent">
                            <h2>{{ currentContent.title }}</h2>
                            <div v-html="currentContent.detail"></div>
                        </div>
                        <el-empty v-else description="请选择知识点" />
                    </el-main>
                </div>
                <el-button
                    class="floating-button"
                    type="primary"
                    circle
                    @click="openNoteDrawer"
                >
                    <el-icon><Edit /></el-icon>
                </el-button>
                <el-drawer
                    v-model="drawerVisible"
                    title="学习笔记"
                    direction="rtl"
                    size="30%"
                    :destroy-on-close="false"
                    :append-to-body="true"
                >
                    <el-form :model="noteForm" label-width="80px">
                        <el-form-item label="标题">
                            <el-input v-model="noteForm.title" />
                        </el-form-item>
                        <el-form-item label="内容">
                            <el-input
                                v-model="noteForm.content"
                                type="textarea"
                                :rows="10"
                            />
                        </el-form-item>
                        <el-form-item>
                            <el-button type="primary" @click="handleSaveNote">保存</el-button>
                        </el-form-item>
                    </el-form>
                </el-drawer>
                <el-dialog
                    v-model="confirmDialogVisible"
                    title="确认保存"
                    width="30%"
                    :append-to-body="true"
                    center
                >
                    <span>确认保存当前笔记吗？</span>
                    <template #footer>
                        <el-button @click="confirmDialogVisible = false">取消</el-button>
                        <el-button type="primary" @click="confirmSaveNote">确认</el-button>
                    </template>
                </el-dialog>
            </el-main>
        </el-container>

        <div class="chat-bubble" @click="toggleChat">
            <img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2z'/%3E%3C/svg%3E" alt="聊天">
        </div>

        <div class="chat-container" id="chatContainer">
            <iframe src="http://121.40.242.43/chatbot/W6TLrJcFFhFE1Zpi" class="chat-iframe"></iframe>
        </div>
    </div>
</template>

<style scoped>
/* 此样式已在下方更新，这里删除以避免重复 */

/* 此样式已在下方更新，这里删除以避免重复 */

.point_content {
    height: auto;
    max-height: calc(100vh - 120px);
    padding: 20px;
    background: #f8f9fa;
    overflow-y: auto;
}

.floating-button {
    position: fixed;
    right: 30px;
    bottom: 30px;
    width: 50px;
    height: 50px;
    box-shadow: 0 2px 12px rgba(0,0,0,0.15);
    z-index: 100;
}

.knowledge-point {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
}

.course-selector {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 20px;
}

.course-title {
    margin: 0;
    font-size: 18px;
    font-weight: bold;
    color: #303133;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 300px;
}

/* 添加新样式以优化布局 */
.course-study-container {
    height: 100vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-height: 0;
}

.compact-main {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    padding: 0;
    min-height: 0;
}

.main-content {
    flex: 1;
    display: flex;
    overflow: hidden;
    min-height: 0; /* 对于Firefox很重要 */
}

.point_list {
    border-right: 1px solid #eee;
    overflow-y: auto;
    max-height: calc(100vh - 80px);
    min-height: 0;
}

/* 让知识点文本可以自动换行 */
.knowledge-point span {
    word-break: break-word;
    flex: 1;
    padding-right: 5px;
}

/* 让标签保持最小宽度 */
.knowledge-point .el-tag {
    flex-shrink: 0;
}

/* 知识点内容区域中的内容样式 */
.point_content h2 {
    margin-top: 0;
    font-size: 1.5rem;
}

.point_content div[v-html] {
    overflow-wrap: break-word;
    word-wrap: break-word;
}
.chat-bubble {
    position: fixed;
    bottom: 20px;
    right: 20px;
    width: 60px;
    height: 60px;
    background-color: #007bff;
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    box-shadow: 0 2px 10px rgba(0,0,0,0.2);
    z-index: 1000;
}

.chat-bubble img {
    width: 30px;
    height: 30px;
}

.chat-container {
    position: fixed;
    bottom: 100px;
    right: 20px;
    width: 350px;
    height: 500px;
    background: white;
    border-radius: 10px;
    box-shadow: 0 2px 10px rgba(0,0,0,0.2);
    display: none;
    z-index: 999;
}

.chat-iframe {
    width: 100%;
    height: 100%;
    border: none;
    border-radius: 10px;
}
</style>
